package com.boful.common.file.model;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;

abstract class FileSystem {
	/**
	 * Return the FileSystem object representing this platform's local
	 * filesystem.
	 */
	public static FileSystem getFileSystem(String url) {
		if (url.startsWith("smb") || url.startsWith("\\\\")) {
			try {
				return new SMBFileSystem(url);
			} catch (Exception e) {
				return null;
			}
		}else if(new File(url).exists()){
			return new LocalFileSystem(url);
		}
		return null;
	}

	/* -- Normalization and construction -- */

	/**
	 * Return the local filesystem's name-separator character.
	 */
	public abstract char getSeparator();

	/**
	 * Convert the given pathname string to normal form. If the string is
	 * already in normal form then it is simply returned.
	 */
	public abstract String normalize(String path);

	/**
	 * Return the parent pathname string to be used when the parent-directory
	 * argument in one of the two-argument NetFile constructors is the empty
	 * pathname.
	 */
	public abstract String getDefaultParent();

	/* -- Path operations -- */

	/**
	 * Tell whether or not the given abstract pathname is absolute.
	 */
	public abstract boolean isAbsolute();

	/* -- Attribute accessors -- */

	/**
	 * Check whether the NetFile or directory denoted by the given abstract
	 * pathname may be accessed by this process. The second argument specifies
	 * which access, ACCESS_READ, ACCESS_WRITE or ACCESS_EXECUTE, to check.
	 * Return false if access is denied or an I/O error occurs
	 */

	/**
	 * Return the time at which the NetFile or directory denoted by the given
	 * abstract pathname was last modified, or zero if it does not exist or some
	 * other I/O error occurs.
	 */
	public abstract long getLastModifiedTime();

	/**
	 * Return the length in bytes of the NetFile denoted by the given abstract
	 * pathname, or zero if it does not exist, is a directory, or some other I/O
	 * error occurs.
	 */
	public abstract long getLength();

	/* -- NetFile operations -- */

	/**
	 * Delete the NetFile or directory denoted by the given abstract pathname,
	 * returning <code>true</code> if and only if the operation succeeds.
	 */
	public abstract boolean delete();

	/**
	 * List the elements of the directory denoted by the given abstract
	 * pathname. Return an array of strings naming the elements of the directory
	 * if successful; otherwise, return <code>null</code>.
	 */
	public abstract String[] list();

	public abstract NetFile[] listFiles();

	/**
	 * Create a new directory denoted by the given abstract pathname, returning
	 * <code>true</code> if and only if the operation succeeds.
	 */
	public abstract boolean createDirectory();

	/**
	 * Rename the NetFile or directory denoted by the first abstract pathname to
	 * the second abstract pathname, returning <code>true</code> if and only if
	 * the operation succeeds.
	 */
	public abstract boolean rename(NetFile f2);

	/* -- Filesystem interface -- */

	/**
	 * List the available filesystem roots.
	 */

	public abstract String getScheme();

	public abstract InputStream getInputStream();

	public abstract OutputStream getOutputStream();

	public abstract String getName();

	public abstract boolean exist();

	public abstract boolean copyTo(NetFile destFile);

	public abstract String getContentType();

	public abstract boolean isDirectory();

}